package com.cqhz.quwan.ui.buy

import android.content.Context
import android.content.Intent
import android.database.DataSetObserver
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.ListView
import android.widget.TextView
import com.blankj.utilcode.util.KeyboardUtils
import com.cqhz.quwan.APP
import com.cqhz.quwan.ActivityInject
import com.cqhz.quwan.R
import com.cqhz.quwan.common.KeyContract
import com.cqhz.quwan.model.*
import com.cqhz.quwan.mvp.buy.LotteryBettingContract
import com.cqhz.quwan.mvp.buy.LotteryBettingPresenter
import com.cqhz.quwan.service.API
import com.cqhz.quwan.ui.activity.GoPaymentActivity
import com.cqhz.quwan.ui.base.GoBackActivity
import com.cqhz.quwan.ui.base.WebViewActivity
import com.cqhz.quwan.ui.buy.adapter.BettingAdapter
import com.cqhz.quwan.ui.login.LoginActivity
import com.cqhz.quwan.util.*
import me.militch.quickcore.core.HasDaggerInject
import javax.inject.Inject




class LotteryBettingActivity : GoBackActivity(),LotteryBettingContract.View, LoginSubscribe,HasDaggerInject<ActivityInject>,PayEventSubscribe {
    val log = CLogger(this::class.java)
    override fun doPayFinish() {
        finish()
    }


    override fun toPay(orderResp: OrderResp) {
        hintLoading()
        val intent = Intent(this, GoPaymentActivity::class.java)
        intent.putExtra(KeyContract.Amount,orderResp.payAmount?.toDouble())
        intent.putExtra(KeyContract.ActualAmount,orderResp.payAmount?.toDouble())
        intent.putExtra(KeyContract.PeriodNum,periodNum)
        intent.putExtra(KeyContract.LotteryType,lotteryType)
        intent.putExtra(KeyContract.LotteryName,lotteryName)
        intent.putExtra(KeyContract.OrderId,orderResp.id)
        startActivity(intent)
    }

    override fun inject(t: ActivityInject?) {
        t?.inject(this)
    }

    override fun onDestroy() {
        LoginObserver.unregister(this)
        PayEventObserver.unregister(this)
        lotteryBettingPresenter.detachView()
        super.onDestroy()
    }

    override fun login(loginBean: LoginBean?) {

    }

    private val mListView by v<ListView>(R.id.betting_lv)
    private val genRandomOneBtn by v<TextView>(R.id.btn_betting_gen_random_one)
    private val manualSelectBtn by v<TextView>(R.id.btn_manual_select)
    private val genRandomFiveBtn by v<TextView>(R.id.btn_betting_gen_random_five)
    private val clearAllBtn by v<TextView>(R.id.btn_clear_all)
    private val stakeTv by v<TextView>(R.id.tv_betting_stake)
    private val rootView by v<LinearLayout>(R.id.betting_root_view)
    private val timesTv by v<TextView>(R.id.tv_betting_times)
    private val amountTv by v<TextView>(R.id.tv_betting_amount)
    private val addTimesTv by v<TextView>(R.id.tv_betting_add)
    private val minusTimesTv by v<TextView>(R.id.tv_betting_minus)
    private val timesEdit by v<EditText>(R.id.edit_betting_times)
    private val buyTv by v<TextView>(R.id.tv_betting_buy)
    private lateinit var adapter:BettingAdapter
    @Inject lateinit var lotteryBettingPresenter: LotteryBettingPresenter
    private var timesNum:Int = 10
    private var stakeNum:Long = 0
    private var amountNum:Long = 0
    private var lotteryId:String? = null
    private var periodNum:String? = null
    private var lotteryName:String? = null
    private var betMethod:NumType.BetMethod? = null
    private var lotteryType:Int = KeyContract.LotteryType_SSQ
    override fun titleBarText(): String? {
        return "投注"
    }
    override fun layout(): Int {
        return R.layout.activity_betting
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        val item = intent?.getSerializableExtra(KeyContract.BettingItem) as BettingItem ?
        val isReset = intent?.getBooleanExtra(KeyContract.IsReset,false)?:false
        val resetIndex = intent?.getIntExtra(KeyContract.ResetIndex,-1)?:-1
        val genCount = intent?.getIntExtra(KeyContract.Gen,-1)?:-1
        betMethod = intent?.getSerializableExtra(KeyContract.BetMethod) as NumType.BetMethod?
        if(isReset&&resetIndex!=-1&&item != null){
            adapter.removeItemIndex(resetIndex)
            adapter.addItem(item,0)
        }else if(genCount>0){
            adapter.addData(genRandomWrapped(genCount),0)
        }else if(item != null){
            adapter.addItem(item,0)
        }
    }


    override fun initView() {
        LoginObserver.register(this)
        PayEventObserver.register(this)
        lotteryBettingPresenter.attachView(this)
        lotteryId = intent.getStringExtra(KeyContract.LotteryId)
        lotteryName = intent.getStringExtra(KeyContract.LotteryName)
        periodNum = intent.getStringExtra(KeyContract.PeriodNum)
        betMethod = intent.getSerializableExtra(KeyContract.BetMethod) as NumType.BetMethod?
        val item = intent.getSerializableExtra(KeyContract.BettingItem) as BettingItem?
        val genCount = intent.getIntExtra(KeyContract.Gen,-1)
        adapter = BettingAdapter(this,lotteryId!!)

        addTimesTv.setOnClickListener {
            timesNum+=1
            resetLabel()
        }
        minusTimesTv.setOnClickListener {
            if(timesNum>1){
                timesNum-=1
                resetLabel()
            }
        }

        adapter.registerDataSetObserver(object : DataSetObserver() {
            override fun onChanged() {
                stakeNum = adapter.getTotalStake()
                resetLabel()
                hintLoading()
            }
        })
        buyTv.setOnClickListener {
            val loginInfo = APP.get()!!.loginInfo
            if(adapter.mData.isEmpty()){
                showToast("请至少选择一注")
                return@setOnClickListener
            }
            if(loginInfo != null){
                val betList = ArrayList<OrderBet>()
                for(i: BettingItem in adapter.mData){
                    betList.add(i.betStrWrapper())
                }
                val args = HashMap<String,String>()
                args["userId"] = loginInfo.userId?:""
                args["lotteryId"] = lotteryId.toString()
                args["period"] = periodNum.toString()
                args["buyWay"] = "0"
                args["payAmount"] = amountNum.toString()
                args["status"] = "0"
                args["realName"] = ""
                args["mobile"] = ""
                args["idCard"] = ""
                args["betNum"] = stakeNum.toString()
                args["betTimes"] = timesNum.toString()
                args["orderBetJson"] = betList.json()
                showLoading("正在加载中...")
                lotteryBettingPresenter.postOrder(args)
            }else {
                toIntent(LoginActivity::class.java)
            }
        }
        mListView.adapter = adapter
        genRandomOneBtn.setOnClickListener {
            adapter.addData(genRandomWrapped(1),0)
        }
        genRandomFiveBtn.setOnClickListener {
            adapter.addData(genRandomWrapped(5),0)
        }
        clearAllBtn.setOnClickListener {
            timesNum = 1
            adapter.clearData()
        }
        manualSelectBtn.setOnClickListener {
            val intent = Intent(this,BettingMachineActivity::class.java)
            intent.putExtra(KeyContract.LotteryId,lotteryId)
            startActivity(intent)
        }
        val footerView = LayoutInflater.from(this).inflate(R.layout.layout_footer,null,false)
        val xieyi = footerView.findViewById<TextView>(R.id.footer_xieyi)
        xieyi.setOnClickListener {
            val intent = Intent(this, WebViewActivity::class.java)
            intent.putExtra(KeyContract.Title,"服务协议")
            intent.putExtra(KeyContract.Url, API.TzXieyi)
            startActivity(intent)
        }
        mListView.addFooterView(footerView)
        if(item != null){
            adapter.addItem(item)
        }else if(genCount > 0){
            adapter.addData(genRandomWrapped(genCount))
        }

        timesEdit.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {

            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                timesNum = try{
                    s?.toString()?.toInt()?:0
                }catch (e:NumberFormatException){
                    10
                }
                resetLabel(false)
            }

        })
        timesEdit.setOnEditorActionListener({ view: View?, i:Int?, event: KeyEvent? ->
            when(i){
                EditorInfo.IME_ACTION_DONE ->  {
                    timesEdit.clearFocus()
                    KeyboardUtils.hideSoftInput(this)
                }
            }
            false
        })
    }


    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (ev?.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            if (isShouldHideInput(v, ev)) {
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
                imm?.hideSoftInputFromWindow(v.windowToken, 0)
            }
            return super.dispatchTouchEvent(ev)
        }
        // 必不可少，否则所有的组件都不会有TouchEvent了
        if (window.superDispatchTouchEvent(ev)) {
            return true
        }
        return super.dispatchTouchEvent(ev)
    }
    private fun isShouldHideInput(v:View, event:MotionEvent):Boolean {
        if (v is EditText) {
            val leftTop = intArrayOf(0, 0)
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return if (event.x > left && event.x < right
                    && event.y > top && event.y < bottom) {
                // 点击的是输入框区域，保留点击EditText的事件
                false
            } else {
                //使EditText触发一次失去焦点事件
                v.setFocusable(false)
                //                v.setFocusable(true); //这里不需要是因为下面一句代码会同时实现这个功能
                v.setFocusableInTouchMode(true)
                true
            }
        }
        return false
    }

    private fun resetLabel(flg:Boolean=true){
        amountNum = stakeNum*2*timesNum
        stakeTv.text = "$stakeNum"
        timesTv.text = "$timesNum"
        amountTv.text = "$amountNum"
        if (flg){
            timesEdit.setText("$timesNum")
        }
//        timesEdit.setText("$timesNum")
    }
    private fun randomBettingItem():BettingItem?{
        val redBalls = when(lotteryId){
            "11" -> (1..33).random(6).toList().sorted()
            "14" -> (1..35).random(5).toList().sorted()
            else -> null
        }
        val blueBalls = when(lotteryId){
            "11" -> (1..16).random(1).toList().sorted()
            "14" -> (1..12).random(2).toList().sorted()
            else -> null
        }
        if (redBalls != null && blueBalls != null){
            val mAllStake = redBalls.size.combine(when(lotteryId){
                "11" -> 6
                "14" -> 5
                else -> 0
            })* blueBalls.size.combine(when(lotteryId){
                "11" -> 1
                "14" -> 2
                else -> 0
            })
            return BettingItem(redBalls,blueBalls,Lottery.TYPE_LOTTO_NORMAL,mAllStake)
        }
        val numData = betMethod?.betLines?.map {
                it.nums?.random(it.selectMin?:1)?.sorted()!!
        }
        val typeId = when(betMethod?.id){
            "1" -> Lottery.TYPE_NUM_ZX
            "2" -> Lottery.TYPE_NUM_Z3_SINGLE
            "3" -> Lottery.TYPE_NUM_Z3_MULTI
            "4" -> Lottery.TYPE_NUM_Z6
            else -> -1
        }
        val item = BettingItem(null,null,typeId,getAllStake(numData!!))
        item.betBits = numData
        return item
    }


    private fun getAllStake(numbers: List<List<Int>>):Long{
        return  when(lotteryId){
            "12" -> when(betMethod?.id){
                "1" -> if (numbers.size > 2) zxStake(numbers) else 0
                "2" -> if (numbers.size > 1) zsdStake(numbers) else 0
                "3" -> if (numbers.isNotEmpty()) zsfStake(numbers) else 0
                "4" -> if (numbers.isNotEmpty()) zlStake(numbers) else 0
                else -> 0
            }
            "16" -> when(betMethod?.id){
                "1" -> if (numbers.size > 2) zxStake(numbers) else 0
                "3" -> if (numbers.isNotEmpty()) zsfStake(numbers) else 0
                "4" -> if (numbers.isNotEmpty()) zlStake(numbers) else 0
                else -> 0
            }
            "15" -> when(betMethod?.id){
                "1" -> if (numbers.size > 6) zxStake(numbers) else 0
                else -> 0
            }
            else -> 0
        }
    }

    private fun zsdStake(numbers: List<List<Int>>):Long{
        return if(numbers[0].isNotEmpty() && numbers[1].isNotEmpty()) 1 else 0
    }
    private fun zxStake(numbers:List<List<Int>>):Long{
        var stake = 1
        for (number in numbers){
            stake *= number.size
        }
        return stake.toLong()
    }
    private fun zsfStake(numbers:List<List<Int>>):Long{
        return numbers[0].size.combine(2)*2
    }

    private fun zlStake(numbers:List<List<Int>>):Long{
        return numbers[0].size.combine(3)
    }

    private fun genRandomWrapped(count:Int):List<BettingItem>{
        val temp = ArrayList<BettingItem>()
        for(i in 1..count){
            val item = randomBettingItem()
            if(item != null) {
                temp.add(item)
            }
        }
        return temp
    }


}